package com.summer.controller.appUser;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.summer.entity.SourceUserLoginInfo;
import com.summer.entity.UserInfo;
import com.summer.service.IUserInfoService;
import com.summer.service.SourceUserLoginInfoService;
import com.summer.util.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
import java.util.*;

/**
 * 用户登录注册Controller
 */
@Slf4j
@RestController
@RequestMapping("/v1.0/api/app")
public class UserLoginRegisterController {

    @Autowired
    private IUserInfoService userInfoService;
    @Resource
    private SourceUserLoginInfoService sourceUserLoginInfoService;
    @Resource
    private RedisUtil redisUtil;
    /**
     * 通过手机号验证用户，该功能实现于切换用户登录界面和注册界面，对该手机号进行判断
     * @param phoneNumber
     * @return
     */
    @GetMapping("/user/{phoneNumber}")
    public Object verifyPhone(@PathVariable("phoneNumber")
                                  @NotNull(message = "手机号"+Constant.PARAM_IS_NOT_BALANK)
                                  @Pattern(regexp = Constant.PHONE_REGULAR,message = Constant.PHONE_IS_ILLEGAL)
                                  String phoneNumber)throws Exception{
        log.info("start invoke UserLoginRegisterController  verifyPhone phoneNumber={}",phoneNumber);
        if (!ValidateUtil.isMobileNumber(phoneNumber)){
            return new CallBackResult(Constant.RESULT_BAD_STATUS,Constant.PHONE_IS_ILLEGAL);
        }
        //查询手机号码
        HashMap<String, Object> map = new HashMap<>();
        map.put("phone",phoneNumber);
        List<UserInfo> userInfos = userInfoService.findParams(map);
        if (userInfos.size()==0){ //用户不存在
            HashMap<String, Object> resultMap = new HashMap<>();
            resultMap.put("flag",1);//flag为1：用户去注册页面，并携带获取手机验证码的地址给前端
            return new CallBackResult(CallBackResult.SUCCESS,"用户名不存在，请注册！",resultMap);
        }else {//用户名存在
            HashMap<String, Object> resultMap = new HashMap<>();
            resultMap.put("flag",2);//flag为2：用户去登录页面
           return new CallBackResult(CallBackResult.SUCCESS,"用户名存在，请登录！",resultMap);
        }
    }

    /**
     * 用户注册
     * @param jsonData
     * @param request
     * @return
     */
    @PostMapping("/register")
    public Object register(@RequestBody String jsonData,HttpServletRequest request)throws Exception{
        Map<String, Object> params = JSONObject.parseObject(jsonData);
         log.info("start invoke UserLoginRegisterController  register jsonData={}", params.toString());
        String phoneNumber = (String) params.get("phoneNumber");
        if (!ValidateUtil.isMobileNumber(phoneNumber)){//手机号码非法
            return new CallBackResult(Constant.RESULT_BAD_STATUS,Constant.PHONE_IS_ILLEGAL);
        }
        String password = (String) params.get("password");
        if (StringUtils.isEmpty(password)){
            return new CallBackResult(Constant.RESULT_BAD_STATUS,"密码不能为空");
        }
        if (!redisUtil.hasKey(phoneNumber+Constant.PHONE_CAPTCHA_SUFFIX)){//验证码失效
            return new CallBackResult(Constant.RESULT_BAD_STATUS,Constant.CAPTCHA_IS_NOT_EXIST);
        }
        String smsCode  = (String) params.get("smsCode");
        if (redisUtil.get(phoneNumber+Constant.PHONE_CAPTCHA_SUFFIX).equals(smsCode)){
            UserInfo userInfo = new UserInfo();
            userInfo.setPhone(phoneNumber);
            String randomSalt = RandomUtil.getRandomSalt();
            userInfo.setPassword(MD5Util.md5(password+randomSalt));
            userInfo.setLoginPwdSalt(randomSalt);
            userInfo.setCreateIp(IPUtils.getIpAddr(request));
            int insert = userInfoService.insertSelective(userInfo);
            if (insert>0){
                CallBackResult callBackResult = new CallBackResult();
                callBackResult.setCode(CallBackResult.SUCCESS);
                callBackResult.setMessage("注册成功！");
                //注册成功返回的数据
                HashMap<String, Object> resultMap = new HashMap<>();
                callBackResult.setData(resultMap);
                return callBackResult;
            }else {
                return new CallBackResult(Constant.RESULT_BAD_STATUS,"注册失败");
            }
        }else {
            return new CallBackResult(Constant.RESULT_BAD_STATUS,"验证码错误");
        }
    }
    /**
     * 用户登录
     * @param jsonData
     * @param request
     * @return
     * @throws Exception
     */
    @PostMapping("/login")
    public Object login(@RequestBody String jsonData,HttpServletRequest request)throws Exception{
        Map<String, Object> params = JSONObject.parseObject(jsonData);
         log.info("start invoke UserLoginRegisterController  login jsonData={}", params.toString());
        String phoneNumber = (String) params.get("phoneNumber");
        if (!ValidateUtil.isMobileNumber(phoneNumber)){//手机号码非法
            return new CallBackResult(Constant.RESULT_BAD_STATUS,Constant.PHONE_IS_ILLEGAL);
        }
        String password = (String) params.get("password");
        Map<String, Object> map = new HashMap<>();
        map.put("phone",phoneNumber);
        List<UserInfo> userInfos = userInfoService.findParams(map);
        if (userInfos.size()>0){
            String MD5Password = MD5Util.md5(password + userInfos.get(0).getLoginPwdSalt());
            if (userInfos.get(0).getPassword().equals(MD5Password)){
                if (userInfos.get(0).getStatus() == Constant.USER_STATUS){
                    String token = JwtUtil.generateToken(userInfos.get(0).getPhone(), userInfos.get(0).getId().longValue());
                    //用户对象转换JSON字符串
                    String userInfoJSONStr = JSON.toJSONString(userInfos.get(0));
                    redisUtil.set(Constant.APP_TOKEN_PREFIX+token,userInfoJSONStr,Constant.TOKEN_EXPIRATION_TIME);//过期时间一周
                    if (redisUtil.hasKey(Constant.APP_TOKEN_PREFIX+token)){
                        //查询该用户登录是否有登录日志
                        List<SourceUserLoginInfo> loginInfos = sourceUserLoginInfoService.findByPhone(phoneNumber);
                        SourceUserLoginInfo userLoginInfo = new SourceUserLoginInfo();
                            if (loginInfos.size() > Constant.LIST_SIZE_LENTH_ZORE){
                                userLoginInfo.setPhoneNumber(phoneNumber);
                                userLoginInfo.setIpAddress(IPUtils.getIpAddr(request));
                                userLoginInfo.setSourceChannelCode((String) params.get("channelCode"));
                                userLoginInfo.setLoginTimes(loginInfos.size()+1);
                                userLoginInfo.setLoginTime(new Date());
                                sourceUserLoginInfoService.save(userLoginInfo);
                            }else {
                                userLoginInfo.setPhoneNumber(phoneNumber);
                                userLoginInfo.setIpAddress(IPUtils.getIpAddr(request));
                                userLoginInfo.setSourceChannelCode((String) params.get("channelCode"));
                                userLoginInfo.setLoginTimes(1);
                                userLoginInfo.setLoginTime(new Date());
                                sourceUserLoginInfoService.save(userLoginInfo);
                            }
                           //添加登录成功后要返回的数据
                        CallBackResult callBackResult = new CallBackResult();
                        callBackResult.setCode(200);
                        callBackResult.setMessage("登录成功");
                        Map<String,Object> resultMap=new HashMap<String,Object>();
                        resultMap.put("phoneNumber",userInfos.get(0).getPhone());
                        resultMap.put("sex",userInfos.get(0).getSex());//'性别 0未知 1男 2女 3其他
                        resultMap.put("realName",userInfos.get(0).getRealName());
                        resultMap.put("headPortrait",userInfos.get(0).getHeadPortrait());
                        resultMap.put("token",token);
                        callBackResult.setData(resultMap);
                        return callBackResult;
                    }else {
                        return new CallBackResult(Constant.RESULT_BAD_STATUS,"token生成失败");
                    }
                }else {
                    return new CallBackResult(Constant.RESULT_BAD_STATUS,Constant.USER_FORBIDDEN);//用户被禁用
                }
            }else{
                return new CallBackResult(Constant.RESULT_BAD_STATUS,"密码错误，请重新输入");
            }
        }else {
            return new CallBackResult(Constant.RESULT_BAD_STATUS,"用户不存在，请重新输入");
        }
    }
}
